/*
 *   Copyright (c) 2010-2022, SIUFUNG
 */
package net.siufung.market.base.user.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.siufung.core.model.enums.DeletedEnum;
import net.siufung.core.model.enums.InitializeEnum;
import net.siufung.market.base.user.mapper.IUserMapper;
import net.siufung.market.base.user.mapper.entity.User;
import net.siufung.market.base.user.mapper.entity.UserDetail;
import net.siufung.market.base.user.mapper.entity.UserRole;
import net.siufung.market.base.user.service.IUserDetailService;
import net.siufung.market.base.user.service.IUserRoleService;
import net.siufung.market.base.user.service.IUserService;
import net.siufung.mybatis.base.BaseServiceImpl;
import net.siufung.security.api.service.passwd.ILoginPasswdService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;

/**
 * 系统用户表 数据服务实现
 *
 * @author 陈建峰
 * @since 2022-07-05 16:14:50
 */
@Slf4j
@AllArgsConstructor
@Service(value = "userService")
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends BaseServiceImpl<IUserMapper, User> implements IUserService {

    private final IUserDetailService userDetailService;
    private final IUserRoleService userRoleService;
    private final ILoginPasswdService loginPasswdService;

    @Override
    public boolean save(User user, Integer[] roleIds) {
        user.setLoginPwd(loginPasswdService.getInitPassword());
        if(super.save(user)){
            if(ObjectUtil.isNotEmpty(roleIds)){
                UserRole userRole;
                List<UserRole> userRoleList = Lists.newArrayList();
                for (Integer roleId: roleIds) {
                    userRole = new UserRole();
                    userRole.setUserId(user.getId());
                    userRole.setRoleId(roleId);
                    userRole.setTenantId(user.getTenantId());
                    userRoleList.add(userRole);
                }
                userRoleService.saveBatch(userRoleList);
            }
            return Boolean.TRUE;
        };
        return Boolean.FALSE;
    }

    @Override
    public boolean save(User user, UserDetail userDetail, Integer[] roleIds) {
        if(this.save(user, roleIds)){
            if(Objects.nonNull(userDetail)){
                userDetail.setUserId(user.getId());
                userDetailService.save(userDetail);
            }
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean updateById(User user, Integer[] roleIds) {
        if(super.updateById(user)){
            userRoleService.remove(new LambdaQueryWrapper<UserRole>()
                    .eq(UserRole::getUserId, user.getId()));
            UserRole userRole;
            List<UserRole> userRoleList = Lists.newArrayList();
            if(ObjectUtil.isNotEmpty(roleIds)){
                for (Integer roleId: roleIds) {
                    userRole = new UserRole();
                    userRole.setUserId(user.getId());
                    userRole.setRoleId(roleId);
                    userRole.setTenantId(user.getTenantId());
                    userRoleList.add(userRole);
                }
                userRoleService.saveBatch(userRoleList);
            }
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean updateById(User user, UserDetail userDetail, Integer[] roleIds) {
        if(this.updateById(user, roleIds)){
            userDetailService.remove(
                    new LambdaQueryWrapper<UserDetail>().eq(UserDetail::getUserId, user.getId()));
            userDetail.setUserPhone(user.getMobile());
            userDetailService.save(userDetail);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean updateById(User user, UserDetail userDetail) {
        if(this.updateById(user)){
            userDetailService.remove(
                    new LambdaQueryWrapper<UserDetail>().eq(UserDetail::getUserId, user.getId()));
            userDetail.setUserPhone(user.getMobile());
            userDetailService.save(userDetail);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean updateStatusById(Serializable id, DeletedEnum deletedEnum) {
        return super.update(
                new LambdaUpdateWrapper<User>()
                        .eq(User::getId, id)
                        .set(User::getDeleted, deletedEnum.getValue()));
    }

    @Override
    public boolean removeById(Serializable id) {
        if(super.removeById(id)){
            userDetailService.remove(new LambdaQueryWrapper<UserDetail>()
                    .eq(UserDetail::getUserId, id));
            userRoleService.remove(new LambdaQueryWrapper<UserRole>()
                    .eq(UserRole::getUserId, id));
            return Boolean.TRUE;
        };
        return Boolean.FALSE;
    }

    @Override
    public boolean updatePasswd(Integer userId, String loginPasswd) {
        return super.update(
                new LambdaUpdateWrapper<User>()
                        .eq(User::getId, userId)
                        .set(User::getLoginPwd, loginPasswd));
    }

    @Override
    public boolean updateLoginInfo(Integer userId, String loginLastIp, String loginLastDate) {
        return super.update(
                new LambdaUpdateWrapper<User>()
                        .eq(User::getId, userId)
                        .set(User::getLoginLastIp, loginLastIp)
                        .set(User::getLoginLastDate, loginLastDate));
    }

    @Override
    public boolean initialize(Integer userId) {
        return super.update(
                new LambdaUpdateWrapper<User>()
                        .eq(User::getId, userId)
                        .set(User::getInitFlag, InitializeEnum.IS.getValue()));
    }

}